# -*- coding: utf-8 -*-
"""
****************************
@Time    : 2021/4/25 15:45
@Author  : Candy
@File    : article.py
****************************
"""
import datetime
import json
import os
import sys
from urllib.parse import urlparse

from flask import Blueprint, render_template, request, jsonify
from flask_cors import cross_origin
from flask_restful import Api, Resource, abort
from flask_sqlalchemy import SQLAlchemy

from config.db import LOCAL_IP, LOCAL_HOST
from middlewares.auth import login_and_auth_middleware
from models.articles import Article, Cate, Img
from models.response import MyResponse
from models.users import User
from serializers.JSON_ENCODE import MiniJSONEncoder, response_check, mini_filter
from serializers.article import check_title
from serializers.article_serializer import Simple, Detail
from sqlconfig import app
from utils.auth import MiniJWT
from utils.normal import text2md5, build_aid, change_content
from utils.request_err import MyAbort

a_base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(a_base_path)

article = Blueprint('article', __name__)
api = Api(app)


class ArticleAPI(Resource):

    def get(self, aid):
        MyAbort.a_406()
        return jsonify({'code': 200, 'data': aid})

    def put(self, aid):
        return jsonify({'code': 200})

    def delete(self, aid):
        return jsonify({'code': 200})


class ArticlesAPI(Resource):

    def get(self):
        db = SQLAlchemy()
        article_ = db.session.query(Article).all()
        article_ = mini_filter(article_, fields=['title', 'aid', 'uid'], method='NEED')
        return jsonify(response_check(data=article_))


api.add_resource(ArticleAPI, '/api/article/<int:aid>', endpoint='article1')
api.add_resource(ArticlesAPI, '/api/articles/', endpoint='article2')


@article.route('/upload_file', methods=["POST"])
@cross_origin()
def upload_file():
    # 获取图片文件 name = editormd-image-file
    img = request.files.get('editormd-image-file')
    # 生成随机字符串，防止图片名字重复
    ran_str = text2md5(img)
    # 获取后缀名
    end_tag = os.path.splitext(img.filename)[-1]
    # 定义一个图片存放的位置 存放在static下面
    path = os.path.join(a_base_path, 'static', 'doc', 'img')
    # 图片名称 给图片重命名 为了图片名称的唯一性
    img_name = ran_str + end_tag
    # 图片path和名称组成图片的保存路径
    file_path = os.path.join(path, img_name)
    # 保存图片
    img.save(file_path)
    # 这个是图片的访问路径，需返回前端（可有可无）
    url = os.path.join('/static', 'doc', 'img', img_name)
    # 返回图片路径 到前端
    url = f'http://{LOCAL_IP}:{LOCAL_HOST}' + url.replace('\\', '/')
    return {"success": 1, "message": "上传成功", "url": url}


@article.route('/upload', methods=['POST'])
@cross_origin()
@login_and_auth_middleware
def upload(uid):
    db = SQLAlchemy()
    res = MyResponse()
    content = request.form.get('content', '').strip()
    article_title = request.form.get('article_title', '').strip()
    cate_value = request.form.get('cate_value', '').strip()
    tag_value = request.form.get('tag_value', '日常分享').strip()
    if not content or not article_title or not cate_value:
        res.code = 201
        res.status = 'error'
        res.results['message'] = '新增失败 缺少关键参数'
        return jsonify(res.data())
    cate = db.session.query(Cate.id).filter(Cate.cate_value == cate_value).first()
    if not cate:
        res.code = 201
        res.status = 'error'
        res.results['message'] = '新增失败 分类不被允许'
    elif not check_title(article_title):
        res.code = 201
        res.status = 'error'
        res.results['message'] = '新增失败 标题不被允许'
    else:
        try:
            print(cate_value)
            new_article = Article()
            new_article.content = content
            new_article.aid = build_aid()
            new_article.title = article_title
            new_article.cate = cate.id
            new_article.logo = db.session.query(Img).filter(Img.types == cate_value).first().id
            new_article.tags = tag_value
            new_article.add_time = datetime.datetime.now()
            new_article.user_id = uid
            db.session.add(new_article)
            db.session.commit()
            res.status = 'success'
            res.results['message'] = "新增成功"
        except Exception as e:
            print(str(e))
            db.session.rollback()
            res.code = 201
            res.status = 'error'
            res.results['message'] = '新增失败 可能标题已存在'
    return jsonify(res.data())


@article.route('/update_', methods=['POST'])
@cross_origin()
@login_and_auth_middleware
def update_(uid):
    aid = request.form.get('aid', '')
    content = request.form.get('content', '').strip()
    article_title = request.form.get('article_title', '').strip()
    tag_value = request.form.get('tag_value', '日常分享').strip()
    cate_value = request.form.get('cate_value', '').strip()
    db = SQLAlchemy()
    res = MyResponse()
    cate = db.session.query(Cate.id).filter(Cate.cate_value == cate_value).first()
    if not cate:
        res.code = 201
        res.status = 'error'
        res.results['message'] = '修改失败 分类不被允许'
    elif not check_title(article_title):
        res.code = 201
        res.status = 'error'
        res.results['message'] = '修改失败 标题不被允许'
    else:
        update_article = db.session.query(Article).filter(Article.aid == aid).filter(Article.user_id == uid).filter(Article.is_del == 0).first()
        if update_article:
            try:
                update_article.content = content
                update_article.cate = cate.id
                update_article.tags = tag_value
                update_article.title = article_title
                update_article.update_time = datetime.datetime.now()
                db.session.add(update_article)
                db.session.commit()
                res.results['message'] = '修改成功'
            except Exception:
                res.code = 201
                res.status = 'error'
                res.results['message'] = '修改失败 可能标题已存在'
        else:
            res.code = 201
            res.status = 'error'
            res.results['message'] = '修改失败 此博文不属于您'
    return jsonify(res.data())


@article.route('/delete_', methods=['GET'])
@cross_origin()
@login_and_auth_middleware
def delete_(uid):
    aid = request.args.get('aid')
    db = SQLAlchemy()
    res = MyResponse()
    del_article = db.session.query(Article).filter(Article.aid == aid).filter(Article.user_id == uid).first()
    if del_article:
        user_ = db.session.query(User).filter(User.id == del_article.user_id).first()
        try:
            user_.blog_count = user_.blog_count - 1
            del_article.is_del = 1
            db.session.add(del_article, user_)
            db.session.commit()
            res.results['message'] = '删除成功'
        except Exception:
            db.session.rollback()
            res.code = 201
            res.status = 'error'
            res.results['message'] = '删除失败'
    else:
        res.code = 201
        res.status = 'error'
        res.results['message'] = '删除失败 此博文不属于您'
    print(jsonify(res.data()), 111)
    return jsonify(res.data())


@article.route('/new_list', methods=['GET'])
@cross_origin()
def new_list():
    init_sort = {
        "hot_article": Article.rate_star.desc(),
        "new_article": Article.add_time.desc(),
        "view_article": Article.view_count.desc()
    }
    db = SQLAlchemy()
    res = MyResponse()
    u_types = request.args.get('types', '')
    a_type = request.args.get('a_type', '')
    sort_filed = request.args.get('sort', 'star')
    page_num = request.args.get('page_num', '1')
    try:
        page_num = int(page_num)
    except Exception:
        page_num = 1
    sort_filed = init_sort.get(sort_filed, Article.rate_star.desc())
    page_total = 0
    if u_types == '1':  # 查看个人数据
        m = MiniJWT()
        token = request.headers.get('token', 'a.b.c')
        u_id = m.get_aid(token)
        if not a_type:
            article_s = db.session.query(Article).filter(Article.is_del == 0).filter(Article.user_id == u_id).order_by(sort_filed).limit(9).all()
        else:
            article_s = db.session.query(Article).filter(Article.cate == int(a_type)).filter(Article.is_del == 0).filter(Article.user_id == u_id).order_by(sort_filed).limit(9).all()
    else:
        if not a_type:
            page_total = len(db.session.query(Article).filter(Article.is_del == 0).filter(Article.is_public == 1).order_by(sort_filed).all())
            article_s = db.session.query(Article).filter(Article.is_del == 0).filter(Article.is_public == 1).order_by(sort_filed).offset(10 * (int(page_num)-1)).limit(10).all()
        else:
            page_total = len(db.session.query(Article).filter(Article.cate == int(a_type)).filter(Article.is_del == 0).filter(Article.is_public == 1).order_by(sort_filed).all())
            article_s = db.session.query(Article).filter(Article.cate == int(a_type)).filter(Article.is_del == 0).filter(Article.is_public == 1).order_by(sort_filed).offset(10 * (int(page_num)-1)).limit(10).all()
    builder = Simple(source_data=article_s, mode='many') if u_types == '1' else Detail(source_data=article_s, mode='many')
    a_s = builder.result()
    res.results['message'] = a_s
    res.results['page_total'] = page_total
    db.session.remove()
    return jsonify(res.data())


@article.route('/change_public', methods=['GET'])
@cross_origin()
def change_public():
    db = SQLAlchemy()
    res = MyResponse()
    aid = request.args.get('aid', '')
    article_s = db.session.query(Article).filter(Article.aid == aid).first()
    if article_s:
        try:
            article_s.is_public = 0 if article_s.is_public else 1
            db.session.add(article_s)
            db.session.commit()
            res.results['message'] = 'success'
        except Exception:
            db.session.rollback()
            res.code = 201
            res.status = 'error'
            res.results['message'] = 'failed'
    else:
        res.code = 201
        res.status = 'error'
        res.results['message'] = 'failed'
    db.session.remove()
    return jsonify(res.data())


@article.route('/detail', methods=['GET'])
@cross_origin()
def detail():
    aid = request.args.get('aid')
    db = SQLAlchemy()
    res = MyResponse()
    article_ = db.session.query(Article).filter(Article.is_del == 0).filter(Article.aid == aid).first()
    # user_ = db.session.query(User).filter(User.id == article_.user_id).first()
    if article_:
        if not article_.is_public:
            m = MiniJWT()
            token = request.headers.get('token', 'a.b.c')
            print(token)
            u_id = m.get_aid(token)
            if int(u_id) != article_.user_id:
                print(int(u_id), article_.user_id)
                res.code = 201
                res.message = '无权访问'
                return jsonify(res.data())
        user_ = db.session.query(User).filter(User.id == article_.user_id).first()
        # 更新阅读数
        try:
            user_.view_count = user_.view_count + 1
            article_.view_count = article_.view_count + 1
            db.session.add(article_, user_)
            db.session.commit()
        except Exception:
            db.session.rollback()
        user_info = db.session.query(User).filter(User.id == article_.user_id).first()
        res.results['message'] = article_.content
        res.results['name'] = user_info.name
        res.results['title'] = article_.title
        res.results['editor_time'] = str(article_.add_time)
        res.results['tags'] = article_.tags
        res.results['cate'] = db.session.query(Cate).filter(Cate.id == article_.cate).first().cate_value
    else:
        res.code = 201
    return jsonify(res.data())


class TaskAPI(Resource):
    def get(self, id):
        pass

    def put(self, id):
        pass

    def delete(self, id):
        pass





